package controllers

import (
	"fmt"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/gorilla/websocket"
	"net/http"
	"sync"
	"user/common"
)

type ChatController struct {
	beego.Controller
}

type Connect struct {
	Conn *websocket.Conn
	Data chan []byte
}

type Message struct {
	Userid int
	Sendid int
}

var clientMap = make(map[int]*Connect, 0)

var wg sync.WaitGroup

func (c *ChatController) Chat() {
	t := c.GetString("token")
	id, _ := common.ParseToken(t)
	fmt.Println(id)

	userId, _ := c.GetInt("id")
	sendId, _ := c.GetInt("send_id")
	if id != userId {
		c.Data["json"] = map[string]interface{}{
			"code": http.StatusOK,
			"msg":  "请重新登录",
		}
		c.ServeJSON()
		return
	}
	conn, err := (&websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		EnableCompression: false,
	}).Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
	if err != nil {
		fmt.Println("websocket连接失败")
		return
	}
	w := &Connect{
		Conn: conn,
		Data: make(chan []byte, 50),
	}
	m := &Message{
		Userid: userId,
		Sendid: sendId,
	}
	clientMap[userId] = w
	wg.Add(2)
	go SendMsg(w)
	go Recover(w, m)
	wg.Wait()
}

// 发送消息
func SendMsg(w *Connect) {
	defer wg.Done()
	for {
		select {
		case data := <-w.Data:
			err := w.Conn.WriteMessage(websocket.TextMessage, data)
			if err != nil {
				fmt.Println("发送消息失败")
				return
			}
		}
	}
}

// 接受消息
func Recover(w *Connect, m *Message) {
	defer wg.Done()
	for {
		_, msg, err := w.Conn.ReadMessage()
		if err != nil {
			fmt.Println("消息接收失败")
			return
		}
		res, ok := clientMap[m.Sendid]
		if ok {
			res.Data <- msg
		}
	}
}
